﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace Sinchron
{
    internal static class GraphicsFunction
    {
        private const double TwoPi = 2d * Math.PI;

        public static void RenderSinchron(Rectangle area, Graphics graphics)
        {
            double secondOffset = (double)DateTime.Now.Millisecond / 1000d;
            double minuteOffset = ((double)DateTime.Now.Second + secondOffset) / 60d;
            double hourOffset = ((double)DateTime.Now.Minute + minuteOffset) / 60d;
            double dayOffset = ((double)DateTime.Now.Hour + hourOffset) / 24d;

            RenderCosineWave(new Pen(Properties.Settings.Default.DayColour), area, dayOffset, 1, 3, graphics);
            RenderCosineWave(new Pen(Properties.Settings.Default.HourColour), area, hourOffset, 1, 2, graphics);
            RenderCosineWave(new Pen(Properties.Settings.Default.MinuteColour), area, minuteOffset, 1, 1, graphics);
            RenderCosineWave(new Pen(Properties.Settings.Default.SecondColour), area, secondOffset, 1, 0.5, graphics);

            graphics.Flush();
        }

        public static void RenderSinchronBackground(Rectangle area, Graphics graphics)
        {
            int centreX = area.Width / 2;

            var pen = (Pen)Pens.Gray.Clone();
            var brush = new LinearGradientBrush(area, Color.Black, Color.Gray, LinearGradientMode.Vertical);
            pen.Brush = brush;

            graphics.DrawLine(pen, new Point(centreX, 0), new Point(centreX, area.Height));
        }

        public static void RenderCosineWave(Pen pen, Rectangle area, double timeOffset, double xScaleFactor, double yScaleFactor, Graphics graphics)
        {
            RenderCosineWave(pen, area, timeOffset, xScaleFactor, yScaleFactor, true, graphics);
        }

        public static void RenderCosineWave(Pen pen, Rectangle area, double timeOffset, double xScaleFactor, double yScaleFactor, bool usealpha, Graphics graphics)
        {
            Pen currentPen = (Pen)pen.Clone();
            Point lastPoint = Point.Empty;
            bool isFirstPoint = true;

            int segments = Math.Min(500, area.Width);

            for (int x = 0; x < segments; x++)
            {
                double xOffset = (double)x / (double)segments;

                double yOffset = -Math.Cos(TwoPi * ((xScaleFactor * xOffset) + timeOffset)) / (8d / yScaleFactor) + 0.5d;

                int y = (int)(yOffset * (double)area.Height);

                Point thisPoint = new Point((int)(xOffset * area.Width), y);

                if (!isFirstPoint)
                {
                    if (usealpha)
                    {
                        int alpha = (int)((xOffset - timeOffset) * 510) % 510;

                        while (alpha < 0)
                        {
                            alpha += 510;
                        }

                        if (alpha > 255)
                        {
                            alpha = 510 - alpha;
                        }

                        currentPen.Color = Color.FromArgb(255 - alpha, pen.Color);
                    }
                    graphics.DrawLine(currentPen, lastPoint, thisPoint);
                }
                else
                {
                    isFirstPoint = false;
                }

                lastPoint = thisPoint;
            }
        }
    }
}
